using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.ComponentModel.Design;
using System.Reflection;
using EnvDTE;
using Microsoft.Xna.Framework;

namespace XnaDesignerGenerator
{
    [DesignerSerializer(typeof(XnaGameComponentGenerator), typeof(CodeDomSerializer))]
    [Designer(typeof(XnaGameComponentDesigner), typeof(IDesigner))]
    [ToolboxItemFilter("Microsoft.Xna.Framework", ToolboxItemFilterType.Require)]
    public class XnaGameComponent : Component, XnaComponent
    {
        private Microsoft.Xna.Framework.IGameComponent component;

        [Browsable(true)]
        [TypeConverter(typeof(ExpandableObjectConverter))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Microsoft.Xna.Framework.IGameComponent Component
        {
            get { return component; }
            set
            {
                component = value;
                if (parent != null)
                {
                    if (((GameManager)parent).Game != null)
                        ((GameManager)parent).Game.Components.Add(component);
                }
                if (gameComponentType == null)
                    GameComponentType = value.GetType();
                if (project == null)
                {
                    Project projectExistent = (Project)TypeDescriptor.GetConverter(typeof(Project)).ConvertFrom(gameComponentType.Namespace);
                    if (projectExistent != null)
                    {
                        project = projectExistent;
                    }
                }
            }
        }

        private Assembly assembly;

        [Category("Xna")]
        [TypeConverter(typeof(AssemblyListConverter))]
        public Assembly Assembly
        {
            get
            {
                if (assembly == null && (gameComponentType != null || component != null))
                {
                    if (gameComponentType != null)
                        assembly = gameComponentType.Assembly;
                    else
                        assembly = component.GetType().Assembly;
                }
                return assembly;
            }
            set { assembly = value; }
        }


        private Type gameComponentType;

        [Browsable(true)]
        [Category("Xna")]
        [TypeConverter(typeof(GameComponentTypeListConverter))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Type GameComponentType
        {
            get { return gameComponentType; }
            set
            {
                gameComponentType = value;
                assembly = value.Assembly;
            }
        }

        private Component parent;

        [Category("Xna")]
        [Browsable(false)]
        public Component Parent
        {
            get { return parent; }
            set
            {
                parent = value;
                if (component != null)
                    ((GameManager)value).Game.Components.Add(component);
            }
        }

        private EnvDTE.Project project;

        [DesignOnly(true)]
        [Category("Xna")]
        [TypeConverter(typeof(ProjectTypeConverter))]
        public EnvDTE.Project Project
        {
            get { return project; }
            set { project = value; }
        }
    }
}
